import numpy as np
from sklearn.random_projection import GaussianRandomProjection

# 1. 数据生成
np.random.seed(42)
high_dim = 100    # 高维空间维度
low_dim = 10    # 降维后的目标维度
num_points = 1000  # 数据点数量

# 生成高维数据点
data_high_dim = np.random.rand(num_points, high_dim)

# 2. 随机投影矩阵生成
# 生成一个高斯随机矩阵
random_projection_matrix = np.random.normal(size=(high_dim, low_dim))

# 3. 投影到低维空间
data_low_dim = np.dot(data_high_dim, random_projection_matrix)

# 4. 原始距离与投影距离对比
# 选取两个点计算距离
point_a = data_high_dim[0]
point_b = data_high_dim[1]

# 高维空间中的欧氏距离
original_distance = np.linalg.norm(point_a - point_b)

# 低维空间中的欧氏距离
projected_distance = np.linalg.norm(data_low_dim[0] - data_low_dim[1])

# 5. 使用sklearn实现随机投影
# 使用sklearn的GaussianRandomProjection
transformer = GaussianRandomProjection(n_components=low_dim, random_state=42)
data_low_dim_sklearn = transformer.fit_transform(data_high_dim)  # 修正了这里的错误

# 计算sklearn降维后的距离
projected_distance_sklearn = np.linalg.norm(data_low_dim_sklearn[0] - data_low_dim_sklearn[1])

# 6. 输出结果
print(f"原始高维数据点之间的距离: {original_distance:.6f}")
print(f"随机投影降维后数据点之间的距离 (自定义实现): {projected_distance:.6f}")
print(f"随机投影降维后数据点之间的距离 (sklearn实现): {projected_distance_sklearn:.6f}")
print("\n随机投影后的部分数据点:")
print(data_low_dim[:5])  # 显示降维后的前5个数据点